﻿using Microsoft.Maui.Animations;
using Microsoft.Maui.Handlers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UraniumUI.Tests.Core;
public class AnimationReadyHandler : AnimationReadyHandler<BlockingTicker>
{
    public AnimationReadyHandler()
        : base(new TestAnimationManager(new BlockingTicker()))
    {
    }
}

public class AnimationReadyHandlerAsync : AnimationReadyHandler<AsyncTicker>
{
    public AnimationReadyHandlerAsync()
        : base(new TestAnimationManager(new AsyncTicker()))
    {
    }
}

public class AnimationReadyHandler<TTicker> : ViewHandler<IView, object>
    where TTicker : ITicker, new()
{
    public AnimationReadyHandler(IAnimationManager animationManager)
        : base(new PropertyMapper<IView>())
    {
        SetMauiContext(new AnimationReadyMauiContext(animationManager));
    }

    public static AnimationReadyHandler<TTicker> Prepare<T>(params T[] views)
        where T : View
    {
        var handler = new AnimationReadyHandler<TTicker>(new TestAnimationManager(new TTicker()));

        foreach (var view in views)
            view.Handler = handler;

        return handler;
    }

    public static T Prepare<T>(T view, out AnimationReadyHandler<TTicker> handler)
        where T : View
    {
        handler = new AnimationReadyHandler<TTicker>(new TestAnimationManager(new TTicker()));

        view.Handler = handler;

        return view;
    }

    public static T Prepare<T>(T view)
        where T : View
    {
        view.Handler = new AnimationReadyHandler();

        return view;
    }

    protected override object CreatePlatformView() => new();

    public IAnimationManager AnimationManager => ((AnimationReadyMauiContext)MauiContext).AnimationManager;

    public class AnimationReadyMauiContext : IMauiContext, IServiceProvider
    {
        readonly IAnimationManager _animationManager;

        public AnimationReadyMauiContext(IAnimationManager manager = null)
        {
            _animationManager = manager ?? new TestAnimationManager();
        }

        public IServiceProvider Services => this;

        public IMauiHandlersFactory Handlers => throw new NotImplementedException();

        public IAnimationManager AnimationManager => _animationManager;

        public object GetService(Type serviceType)
        {
            if (serviceType == typeof(IAnimationManager))
                return _animationManager;

            var subs = NSubstitute.Substitute.For(typesToProxy: new[] { serviceType }, new object[0]);

            return subs;
        }
    }
}

public static class AnimationReadyWindowExtensions
{
    public static async Task DisableTicker(this AnimationReadyHandler<AsyncTicker> handler)
    {
        await Task.Delay(32);

        ((AsyncTicker)handler.AnimationManager.Ticker).SetEnabled(false);
    }

    public static async Task EnableTicker(this AnimationReadyHandler<AsyncTicker> handler)
    {
        await Task.Delay(32);

        ((AsyncTicker)handler.AnimationManager.Ticker).SetEnabled(true);
    }
}

